{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Networkplot: Visualizing 2D Layouts\n",
    "\n",
    "This example provides how to visualize 2D layouts using networkplot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import graspologic\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Visualizing 2D layout using networkplot\n",
    "\n",
    "### Simulate an adjacency matrix using a stochastic block model\n",
    "\n",
    "The 2-block model is defined as below:\n",
    "\n",
    "\\begin{align*}\n",
    "P = \n",
    "\\begin{bmatrix}0.25 & 0.05 \\\\\n",
    "0.05 & 0.25\n",
    "\\end{bmatrix}\n",
    "\\end{align*}\n",
    "\n",
    "More information on stochastic block models can be found [here](https://microsoft.github.io/graspologic/tutorials/simulations/sbm.html)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from graspologic.simulations import sbm\n",
    "\n",
    "n_communities = [50, 50]\n",
    "p = [[0.25, 0.05], [0.05, 0.25]]\n",
    "\n",
    "np.random.seed(1)\n",
    "A, node_ids = sbm(n_communities, p, return_labels=True)\n",
    "print(A.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Generate a 2D embedding using ASE\n",
    "\n",
    "Adjacency Spectral Embed (ASE) reduces the dimensionality of the input adjacency matrix and estimates its latent positions, generating an embedding in a lower-dimensional space. In this example, ASE embeds the adjacency matrix generated by SBM to two-dimensional space and calculates its coordinates. \n",
    "\n",
    "More information on ASE can be found [here](https://microsoft.github.io/graspologic/tutorials/embedding/AdjacencySpectralEmbed.html?highlight=adjacency)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from graspologic.embed import AdjacencySpectralEmbed\n",
    "\n",
    "ase = AdjacencySpectralEmbed(n_components=2)\n",
    "X = ase.fit_transform(A)\n",
    "\n",
    "print(X.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Visualize 2D layout\n",
    "\n",
    "Note that node colors were determined by communities that were randomly assigned and the node sizes are determined by the number of edges connected to each node. The edge colors for the plot below are based on their source nodes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "from graspologic.plot.plot import networkplot\n",
    "\n",
    "x_pos = X[:,0]\n",
    "y_pos = X[:,1]\n",
    "degrees = np.sum(A, axis=0)\n",
    "\n",
    "plot = networkplot(adjacency=A, x=x_pos, y=y_pos, node_hue=node_ids, palette='deep', node_size=degrees, \n",
    "                   node_sizes=(20, 200), edge_hue='source', edge_alpha=0.5, edge_linewidth=0.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Alternatively, we can also use a pandas dataframe and use x, y, node_hue, and node_size as keys. Note that for the plot below, the edge colors are determined by their target nodes by assigning edge_hue as 'target'."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "index = range(X.shape[0])\n",
    "node_df = pd.DataFrame(index=index)\n",
    "node_df.loc[:, 'x'] = X[:,0]\n",
    "node_df.loc[:, 'y'] = X[:,1]\n",
    "node_df.loc[:, 'id'] = node_ids\n",
    "node_df.loc[:, 'degree'] = np.sum(A, axis=0)\n",
    "\n",
    "plot = networkplot(adjacency=A, node_data=node_df, x='x', y='y', node_hue='id', palette='deep', \n",
    "                   node_size='degree', node_sizes=(20, 200), edge_hue='target', edge_alpha=0.5, edge_linewidth=0.5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
